package com.netcracker.db.impl;

import com.netcracker.db.exception.DBException;
import com.netcracker.db.DBManager;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Locale;

public class OracleDBManager implements DBManager {

    private static final String DRIVER = "oracle.jdbc.driver.OracleDriver";

    private Connection connection = null;
    private Statement statement = null;
    
    public OracleDBManager(String url, String login, String password) throws DBException {
        try {
            Locale.setDefault(Locale.ENGLISH);
            Class.forName(DRIVER).newInstance();
            createConnection(url, login, password);
        } catch (ClassNotFoundException ex) {
            throw new RuntimeException("Class " + DRIVER + " not found", ex);
        } catch (InstantiationException ex) {
            throw new RuntimeException("Driver " + DRIVER + " class InstantiationException.", ex);
        } catch (IllegalAccessException ex) {
            throw new RuntimeException("IllegalAccess for " + DRIVER + " class.", ex);
        }
    }

    private void createConnection(String url, String login, String password) throws DBException {
        try {
            connection = DriverManager.getConnection(url, login, password);
            connection.setAutoCommit(false);
            statement = connection.createStatement();
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public void executeUpdate(String sql) throws DBException {
        try {
            statement.executeUpdate(sql);
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public ResultSet execSQL(String sql) throws DBException {
        try {
            return statement.executeQuery(sql);
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public synchronized void close() throws DBException {
        closeConnection();
    }

    private void closeConnection() throws DBException {
        try {
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public PreparedStatement prepareStatement(String sql) throws DBException {
        try {
            return connection.prepareStatement(sql);
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public void commit() throws DBException {
        try {
            connection.commit();
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }

    @Override
    public void rollback() throws DBException {
        try {
            connection.rollback();
        } catch (SQLException ex) {
            throw new DBException(ex.getMessage(), ex);
        }
    }
    
}